#====================================================
# Copyright (c) 2006 Continuous Comouting Corp.
# All rights reserved
# XP50 performance test script
# Robert Li 2011-04-08
# Version:1.0.0
# Description:
# TODO: determine year automatically
#====================================================
#!/usr/bin/python
import threading
import time
import re
import sys
import os
import wx
import wx.lib.newevent
import string
import StringIO
import traceback
import crx2Test as Test
import pexpect

# The mutex will protect datas that doesn't change by other threading
mutex = threading.Lock()
XP50_CONFIG_FILE = "/Pkt.cfg"
(AddLogMessageEvent, EVT_ADD_LOG_MESSAGE) = wx.lib.newevent.NewEvent()
(TestCompleteEvent, EVT_TEST_COMPLETE) = wx.lib.newevent.NewEvent()
(TestRuningEvent, EVT_TEST_RUNING) = wx.lib.newevent.NewEvent()class GuiClient:
	def __init__(self, win):
		self.TestTimes = 0
		self.TestInitRes=-1	
		self.stats = {"error":0,"failed" : 0,"passed" : 0 }
		self.win = win
		self.startTime = time.time()
		self.test = Test.Test(self)
		self.event = threading.Event()
		self.logFileName = None
		#csSysLogName will record all log during testing for xp50 performance
		self.csSysLogName = self.set_log_file_name("40GbE Pkt#"+time.strftime("%Y-%m-%d"))
		self.HSysLogFile  = open(self.csSysLogName, "a")
		self.HSysLogFile.close()
	
	def TestInit(self):		
		self.TestStaus1 = 0
		self.TestStaus2 = 0				
		self.info("===================Times:"+str(self.TestTimes)+"=========================")		self.info("40GbE Pkt Init has started at " + time.strftime("%Y-%m-%d %H:%M:%S"))
		self.TestInitRes = -1
		try:
			self.test.Init_Device()			
			self.info("Check 40GbE Platform Golden Board Slots have finished")
			if (self.test.init() <> 1):
				self.TestInitRes = 0
				print "TestInit: is failed!"
				sys.stdout.flush()				
				return 0				
			else :
				self.TestInitRes = 1						
		except Exception, e:
			print "TestInit: is Fail!"
			sys.stdout.flush()		
			sfile = StringIO.StringIO()	
			traceback.print_exc(file = sfile)			self.error("EXCEPTION:\n" + sfile.getvalue())
			return -1
		print "TestInit: is ok!"
		sys.stdout.flush()
		return 1
	
	def TestRun(self):
		self.info("xp50  started at " +time.strftime("%Y-%m-%d %H:%M:%S"))
		self.event.clear()
		time.sleep(1)			
		if(self.test.run()<>1):
			self.event.clear()
			evt = TestRuningEvent(result = 1)
			wx.PostEvent(self.win, evt)					

		csTimer="00:00:00"
		startTime = time.time()
		self.csTestLen = self.TestTimeInfor()
		self.info("40GbE Pkt  Test Length :"+ self.csTestLen)

		while cmp(csTimer,self.csTestLen) <0:
			#=============Processing Timer=======0Sec====
			el = int(time.time() - startTime)
			csTimer = "%02d:%02d:%02d" % (el / 3600, (el / 60) % 60, el % 60)
			self.csTimer = self.elapsedStr()
			self.info("40GbE Pkt started at " +csTimer)
			time.sleep(1)
			print "QUERY_STATS is starting.............. "
			sys.stdout.flush()			
			if (self.get_cfg("QUERY_STATS:").find("ENABLE")<>-1):
				iQueryStats = 1
				self.test.queryStats()		
			else:
				iQueryStats = 0										
			#=============Processing GUI=========10Sec===

		if(self.test.end()<>1):
			self.event.clear()
			evt = TestRuningEvent(result = 1)
			wx.PostEvent(self.win, evt)
		self.EndTest()

		return 1
		
	def TestTimeInfor(self):
		el = int(self.get_cfg("TESTTIME:"))
		csTestLen="%02d:%02d:%02d" % (el / 3600, (el / 60) % 60, el % 60)
		self.info("40GbE Pkt Time Long :"+csTestLen)
		return csTestLen	
	
	def TestStats(self):		
		Shmm1 = Test.ShmmObj(1)
		Shmm1.ShmmInit()
		time.sleep(10)
		Shmm2 = Test.ShmmObj(2)
		Shmm2.ShmmInit()		
		while (self.TestStaus1<>1)and (self.TestStaus2<>1):
			Shmm1.ShmmRun()
			Shmm2.ShmmRun()
		Shmm1.ShmmEnd()
		Shmm2.ShmmEnd()			
		self.info("===========Save Shmm1 Shmm2  Setting Finish===========")
		self.info("40GbE Pkt   End at " +time.strftime("%Y-%m-%d %H:%M:%S"))#===================================================================================				
#
#===================================================================================
		evt = TestCompleteEvent(result = 1)
		wx.PostEvent(self.win, evt)
		self.info("40GbE Pkt  Testing complete at " + time.strftime("%Y-%m-%d %H:%M:%S"))

		
		
	def EndTest(self):
		global SLOT_SEQ
		self.TestStaus1=1
		self.TestStaus2=1		
		self.startTime = time.time()
		Test.SLOT_SEQ=[]
		self.event.clear()
		self.info("==================END TEST==================")
		
		self.info("40GbE Pkt   End at " +time.strftime("%Y-%m-%d %H:%M:%S"))#===================================================================================				
#
#===================================================================================
		csControlStats=self.guiClient.get_cfg("CONTROL_STATS:")
		if (csControlStats.find("ENABLE")==-1):
			evt = TestCompleteEvent(result = 1)
			wx.PostEvent(self.win, evt)
			self.info("40GbE Pkt  Testing complete at " + time.strftime("%Y-%m-%d %H:%M:%S"))
		
				

	def set_logmsg_file_name(self, csFileName):	
		LOGPATH = self.get_cfg("XP50_LOG_PATH:")	
		csTestSchme = self.get_cfg("TESTSCHME:")	
		self.logMsgFileName = LOGPATH + csFileName+csTestSchme
		return self.logMsgFileName.replace("\n","")

	def set_log_file_name(self,csFileName):
		LOGPATH = self.get_cfg("XP50_LOG_PATH:")
		csTestSchme = self.get_cfg("TESTSCHME:")		
		self.logFileName = LOGPATH + csFileName+csTestSchme
		return self.logFileName.replace("\n","")						

	def set_stats_file_name(self):
		STATSPATH = self.get_cfg("XP50_STATS_PATH:")
		self.logFileName = STATSPATH + "xp50pt.xls"
		return self.logFileName.replace("\n","")		


	def send_logmsg(self, msg):
		stampmsg = "\n" + self.elapsedStr() +" " + msg
		evt = AddLogMessageEvent(msg = stampmsg)
		wx.PostEvent(self.win, evt)

	def send_resultmsg(self, msg):		
		stampmsg = "\n" + msg
		evt = AddLogMessageEvent(msg = stampmsg)
		wx.PostEvent(self.win, evt)

	def info(self, msg):
		global mutex
		mutex.acquire()
		longmsg = "INFO  : " + msg
		self.send_logmsg(longmsg)
		sys.stdout.flush()		
		self.HSysLogFile = open(self.csSysLogName, "a")	
		self.HSysLogFile.write(longmsg+"\n")			
		self.HSysLogFile.close()
		mutex.release()

	def warn(self, msg):
		global mutex
		mutex.acquire()	
		longmsg = "WARN  : " + msg
		self.send_logmsg(longmsg)
		sys.stdout.flush()
		mutex.release()
	
	def result(self, msg):
		self.send_resultmsg(msg)
		sys.stdout.flush()
		
	def passed(self, msg):	
		global mutex
		mutex.acquire()			
		self.stats["passed"] += 1
		longmsg = "PASSED: " + msg
		mutex.release()			
		self.info(longmsg)
		
	def failed(self, msg):
		global mutex
		mutex.acquire()	
		self.stats["failed"] += 1
		longmsg = "FAILED: " + msg
		mutex.release()			
		self.info(longmsg)

	def error(self, msg):
		global mutex
		mutex.acquire()		
		self.stats["error"] = self.stats["error"] + 1
		longmsg = "ERROR : " + msg
		self.send_logmsg(longmsg)			
		sys.stdout.flush()
		mutex.release()

	def elapsedStr(self):
		el = int(time.time() - self.startTime)
		return "%02d:%02d:%02d" % (el / 3600, (el / 60) % 60, el % 60)

	def get_cfg(self, cfg_index):
		try:		
			ret_cfg = "NO_CFG"
			csDir=os.path.abspath(os.path.dirname(sys.argv[0]))+XP50_CONFIG_FILE
			fh = file(csDir,"r+")
			for line in fh:
				if cfg_index.find(string.split(line,":")[0])<>-1:
					ret_cfg = string.split(line,":")[1]
					break
			fh.close()
			return ret_cfg
		except IOError:
			print "Open file error, can't find file: %s" % csDir  
			sys.stdout.flush()			
			return "NO_CFG"
	def Replace_cfg(self, cfg_index,csOldInfo,csNewInfo):
		csNewLine = cfg_index+csNewInfo
		csOldLine = cfg_index+csOldInfo	
		csDir=os.path.abspath(os.path.dirname(sys.argv[0]))+XP50_CONFIG_FILE
		print "Open  file: %s" % csDir +"  replace   "+csOldLine +"  for "+csNewLine
		sys.stdout.flush()		
		try:		
			fp = file(csDir,"r")
			content=fp.read()
			fp.close()
			content =re.sub(csOldLine,csNewLine+'\r',content)			
			fh = file(csDir,"w")
			fh.write(content)
			fh.close()
		except IOError:
			print "Open file error, can't find file: %s" % csDir
			sys.stdout.flush()
			
			
class LogWidget(wx.TextCtrl):
	def __init__(self, parent, id, ident):
		wx.TextCtrl.__init__(self, parent, id, "Messages:",
				size=(200, 100), style=wx.TE_MULTILINE | wx.TE_READONLY |wx.TE_RICH)
	def clear(self):
		self.Refresh()
		self.Clear()
		self.AppendText("Messages:")

class IdeTestBar(wx.Panel):

	def __init__(self, parent):
		self.csSysLogName = ""
		self.test = Test.Test(self)
		wx.Panel.__init__(self, parent, -1, style=wx.SIMPLE_BORDER)
		self.Bind(EVT_ADD_LOG_MESSAGE, self.onAddLogMessage)
		self.Bind(EVT_TEST_COMPLETE, self.onTestComplete)	
		self.Bind(EVT_TEST_RUNING, self.onTestRuning)								
		self.state = "idle"  #state =[Idle,Init,Start,Compelete]
		self.box = wx.BoxSizer(wx.VERTICAL)		self.SetSizer(self.box)
		self.guiClient = GuiClient(self)

		lInitTestSelector = ['LONGTM','SHORTTM']
		lTestSelector=[' ',' ']
		lTestSelector[0] =self.guiClient.get_cfg("TESTSCHME:")
		if lTestSelector[0]== lInitTestSelector[0]:
			lTestSelector = lInitTestSelector
		else:
			 lTestSelector[1]= lInitTestSelector[0]
			 lTestSelector[0]= lInitTestSelector[1]				 	
		self.TestSelector = wx.Choice(self, -1, (100,100),style=wx.ALIGN_CENTER,choices=lTestSelector)
		self.box.Add(self.TestSelector, 0, wx.EXPAND)
		self.TestSelector.Bind(wx.EVT_CHOICE, self.SelectTestType)
		
						self.ctrlBut = wx.Button(self, -1, "Init Test")
		self.box.Add(self.ctrlBut, 0, wx.EXPAND)
		self.ctrlBut.Bind(wx.EVT_BUTTON, self.onInit)						       

		self.stateText = wx.StaticText(self, -1, "IDLE", style=wx.ALIGN_CENTER)
		self.box.Add(self.stateText, 0, wx.EXPAND)
		self.timeText = wx.StaticText(self, -1, "00:00:00", style=wx.ALIGN_CENTER)
		self.box.Add(self.timeText, 0, wx.EXPAND)		
		
		self.etimer = wx.PyTimer(self.tick)
		self.InitGUITestSolt(0)
		
		self.logBut = LogWidget(self,-1, 'LogInfo')
		self.box.Add(self.logBut, 1, wx.EXPAND)

		self.csSysLogName = self.set_log_file_name("40GbEPkt#"+time.strftime("%Y-%m-%d"))
		self.HSysLogFile = open(self.csSysLogName, "a")
		self.HSysLogFile.close()

	def tick(self):	
		self.timeText.SetLabel(self.guiClient.elapsedStr()[-8:])
		self.Refresh()
		
	def InitGUITestSolt(self,iType):
		if iType==0 :
			self.XP501But= wx.Button(self, -1, "Slot:1 XP50:1")
			self.XP501But.SetBackgroundColour('Yellow')
			self.box.Add(self.XP501But,0, wx.EXPAND)
			self.XP501But.Disable()

			self.XP502But= wx.Button(self, -1, "Slot:2 XP50:2")
			self.XP502But.SetBackgroundColour('Yellow')
			self.box.Add(self.XP502But,0, wx.EXPAND)
			self.XP502But.Disable()

			self.XP503But= wx.Button(self, -1, "Slot:3 XP50:3")
			self.XP503But.SetBackgroundColour('Yellow')
			self.box.Add(self.XP503But,0, wx.EXPAND)
			self.XP503But.Disable()

			self.XP504But= wx.Button(self, -1, "Slot:4 XP50:4")
			self.XP504But.SetBackgroundColour('Yellow')
			self.box.Add(self.XP504But,0, wx.EXPAND)
			self.XP504But.Disable()
				
		# Select different state for the GUI setting

		if iType==1 :
			self.XP501But.SetBackgroundColour('Orange')
			self.XP501But.Enable()
			self.onTestLabel("1",self.XP501But)

			self.XP502But.SetBackgroundColour('Orange')
			self.XP502But.Enable()
			self.onTestLabel("2",self.XP502But)

			self.XP503But.SetBackgroundColour('Orange')
			self.XP503But.Enable()
			self.onTestLabel("3",self.XP503But)

			self.XP504But.SetBackgroundColour('Orange')
			self.XP504But.Enable()
			self.onTestLabel("4",self.XP504But)
					
		if iType==2 :
			self.XP501But.Enable()	
			self.XP501But.SetBackgroundColour('Yellow')
			self.XP501But.SetLabel("............End XP501")

			self.XP502But.Enable()	
			self.XP502But.SetBackgroundColour('Yellow')
			self.XP502But.SetLabel("............End XP502"  )

			self.XP503But.Enable()	
			self.XP503But.SetBackgroundColour('Yellow')
			self.XP503But.SetLabel("............End XP503")

			self.XP504But.Enable()	
			self.XP504But.SetBackgroundColour('Yellow')
			self.XP504But.SetLabel("............End XP504")

		if iType==3 :
			self.XP501But.Enable()	
			self.XP501But.SetBackgroundColour('Yellow')
			self.XP501But.SetLabel("Slot:1 XP50:1")

			self.XP502But.Enable()	
			self.XP502But.SetBackgroundColour('Yellow')
			self.XP502But.SetLabel("Slot:2 XP50:2"  )

			self.XP503But.Enable()	
			self.XP503But.SetBackgroundColour('Yellow')
			self.XP503But.SetLabel("Slot:3 XP50:3")

			self.XP504But.Enable()	
			self.XP504But.SetBackgroundColour('Yellow')
			self.XP504But.SetLabel("Slot:4 XP50:4")
						
	def onAddLogMessage(self, event):
		global mutex
		mutex.acquire()		
		self.logBut.SetDefaultStyle(wx.TextAttr(wx.BLACK,wx.WHITE,wx.Font(10,wx.FONTFAMILY_MODERN,wx.FONTSTYLE_NORMAL,wx.FONTWEIGHT_NORMAL)))
		self.logBut.AppendText(event.msg)
		mutex.release()
	
	def set_log_file_name(self, csFileName):		
		LOGPATH = self.guiClient.get_cfg("XP50_LOG_PATH:")
		csTestSchme = self.guiClient.get_cfg("TESTSCHME:")		
		self.logFileName = LOGPATH + csFileName+csTestSchme
		return self.logFileName.replace("\n","")

	def set_logmsg_file_name(self, csFileName):
		LOGMSGPATH = self.guiClient.get_cfg("XP50_LOGMSG_PATH:")
		csTestSchme = self.guiClient.get_cfg("TESTSCHME:")	
		self.logmsgFileName = LOGMSGPATH + csFileName+csTestSchme
		return self.logmsgFileName.replace("\n","")

	def get_ccpupn(self,csSlot):	
		for csStr in self.SLOTPN_SEQ:
			print "ccpuPn is :  %s ...." %csStr
			sys.stdout.flush()		
		return self.SLOTPN_SEQ

	def get_ccpusn(self,csSlot):
		for csStr in self.SLOTSN_SEQ:
			print "ccpuSn is :  %s ...." %csStr
			sys.stdout.flush()		
		return self.SLOTSN_SEQ

	def onTestLabel(self, csSlot,HBut):
	
		global SLOTPN_SEQ
		global SLOTSN_SEQ
		print "Slot:"+ csSlot
		self.csccpupn= Test.SLOTPN_SEQ[int(csSlot)]
		print "P/N:"+	self.csccpupn
		self.csccpusn= Test.SLOTSN_SEQ[int(csSlot)]
		print "S/N:"+	self.csccpusn
		sys.stdout.flush()
		time.sleep(0.1)
		HBut.SetLabel("XP50_S/N:"+self.csccpusn+"  P/N:"+self.csccpupn+"  Slot:"+csSlot+" is running")
		HBut.SetBackgroundColour('Orange')
		self.Refresh()
		self.startTime = time.time()
		
	def InitTestMon(self):
		while (self.guiClient.TestInitRes == -1):
			time.sleep(1)
		if (self.guiClient.TestInitRes == 0):
			self.ctrlBut.Enable()				
			self.ctrlBut.SetLabel("Init Test Again...")
			self.ctrlBut.Bind(wx.EVT_BUTTON,self.onInit)						
			self.TestSelector.Enable()
			print "InitTestMon() is fail . "
			sys.stdout.flush()			
			return 0

		if (self.guiClient.TestInitRes == 1):
			self.ctrlBut.Enable()	
			self.ctrlBut.SetLabel("Test Start")
			self.ctrlBut.Bind(wx.EVT_BUTTON,self.onStart)
			self.InitGUITestSolt(1)
			print "InitTestMon() is ok."
			sys.stdout.flush()
			return 1
	def SelectTestType(self, event):
		self.guiClient.Replace_cfg("TESTSCHME:",self.guiClient.get_cfg("TESTSCHME:"),event.GetString())			
		self.TestSelector.Disable()
	
	def onInit(self, event):

		self.stateText.SetLabel("Init...")
		self.ctrlBut.Disable()
		self.TestSelector.Disable()	
		self.guiClient.TestInitRes==-1
		self.startTime = time.time()			
		self.etimer.Start(1000)
		time.sleep(0.1)
		thread = None
		InitThread = None		
		thread = threading.Thread(target = self.guiClient.TestInit)
		thread.start()	
		time.sleep(0.1)
		thread.join()
		thread = None		
		csTestMsg=""

		self.ctrlBut.Enable()	
		self.ctrlBut.SetLabel("Test Start")
		self.ctrlBut.Bind(wx.EVT_BUTTON,self.onStart)
		self.InitGUITestSolt(1)

	def onStart(self, event):
		self.InitGUITestSolt(1)	
		self.ctrlBut.SetLabel("Test will be Run...")	
		self.ctrlBut.Disable()
		self.TestSelector.Disable()		
		self.stateText.SetLabel("TESTING...")
		self.stateText.SetBackgroundColour(wx.Colour(200, 200, 255))
		thread = None
		thread = threading.Thread(target = self.guiClient.TestRun)
		thread.start()
		
		csControlStats=self.guiClient.get_cfg("CONTROL_STATS:")
		if (csControlStats.find("ENABLE")<>-1):
			StatsThread = None
			StatsThread = threading.Thread(target = self.guiClient.TestStats)
			StatsThread.start()
			
		self.etimer.Start(1000)
		
	def onTestRuning(self, event):
		self.InitGUITestSolt(1)	
							
	def onTestComplete(self, event):
		self.etimer.Stop()
		self.ctrlBut.Enable()
		self.ctrlBut.SetLabel("Test Finish")
		self.ctrlBut.Bind(wx.EVT_BUTTON, self.onClear)
		self.InitGUITestSolt(2)
		self.TestSelector.Enable()

	def onClear(self, event):
		self.ctrlBut.Enable()
		self.ctrlBut.SetLabel("Test Init")
		self.ctrlBut.Bind(wx.EVT_BUTTON, self.onInit)

		self.stateText.SetLabel("IDLE...")
		self.stateText.SetBackgroundColour(wx.Colour(200, 200, 255))		
		self.timeText.SetLabel("00:00:00")
		self.InitGUITestSolt(3)		
		self.logBut.clear()
		global SLOT_SEQ
		Test.SLOT_SEQ = []
		self.TestSelector.Enable()
